#include "CameraManager.h"

#include <OGRE/OgreEntity.h>
#include <OGRE/OgreMovableObject.h>
#include <OGRE/OgreNode.h>

using namespace Viewer;

CameraManager::CameraManager(Ogre::Camera* camera)
    : _camera(camera), _mouseX(-1), _joystick(0)
{      
  angleX = 0;
  angleY = 0;
}

CameraManager::~CameraManager()
{       }

void CameraManager::setJoystick(OIS::JoyStick* joystick)
{
    _joystick = joystick;
}

void CameraManager::attach(Ogre::Entity* object)
{
    _object = object;
    _object->setListener(this);
    _objectPosition = _object->getParentNode()->getPosition();
    objectMoved(_object);
}

bool CameraManager::mousePressed(const OIS::MouseEvent& arg, OIS::MouseButtonID id)
{
    return true;
}

bool CameraManager::mouseReleased(const OIS::MouseEvent& arg, OIS::MouseButtonID id)
{
    return true;
}

bool CameraManager::mouseMoved(const OIS::MouseEvent& arg)
{
    angleX -= 0.01*arg.state.X.rel;
    angleY += 0.01*arg.state.Y.rel;

    updateCamera();
    
    return true;
}

bool CameraManager::axisMoved(const OIS::JoyStickEvent& arg, int axis)
{
    return true;
}

void CameraManager::objectMoved(Ogre::MovableObject* _)
{
    if(!_object->isAttached())
        return;
    
    updateCamera();
}

void CameraManager::nextFrame(const Ogre::FrameEvent& event)
{
    if(_joystick) {
        std::cout << "joystick" << std::endl;
        double jsx = _joystick->getJoyStickState().mAxes.at(3).abs / -32000.0;
        double jsx2 = _joystick->getJoyStickState().mAxes.at(0).abs / -32000.0;
        double jsy = _joystick->getJoyStickState().mAxes.at(1).abs / 32000.0;
        if(jsx < -0.25 || jsx > 0.25)
            angleX += jsx * 0.1;
        if(jsx2 < -0.25 || jsx2 > 0.25)
            angleX += jsx2 * 0.1;
        if(jsy < -0.25 || jsy > 0.25)
            angleY += jsy * 0.1;
    }
    
    updateCamera();
}

void CameraManager::updateCamera()
{
    //std::cout << "x " << angleX << " y " << angleY << std::endl;
    if(angleX >= 2*M_PI) angleX -= 2*M_PI;
    if(angleX < 0) angleX += 2*M_PI;
    
    if(angleY <= M_PI/4 ) angleY = M_PI/4;
    if(angleY > 3*M_PI/4) angleY = 3*M_PI/4;
    
    _objectPosition = _object->getParentNode()->getPosition();
    double d = 200.0;
    _cameraPosition = Ogre::Vector3(d*sin(angleX)*sin(angleY),150+d*cos(angleY),d*cos(angleX)*sin(angleY));
    _camera -> setPosition(_objectPosition + _cameraPosition);
    _camera -> lookAt(_objectPosition + Ogre::Vector3(0,150,0));
}
